package cn.schoolwow.quickdao.module.database.transaction.kit;

import cn.schoolwow.quickdao.domain.DAO;
import cn.schoolwow.quickdao.domain.transaction.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.support.AbstractPlatformTransactionManager;
import org.springframework.transaction.support.DefaultTransactionStatus;

import java.sql.Connection;

/**QuickDAO与Spring接口实现的事务管理器*/
public class QuickDAOPlatformTransactionManager extends AbstractPlatformTransactionManager {
    private Logger logger = LoggerFactory.getLogger(QuickDAOPlatformTransactionManager.class);

    private DAO dao;

    public QuickDAOPlatformTransactionManager(DAO dao) {
        this.dao = dao;
    }

    @Override
    protected Object doGetTransaction() throws TransactionException {
        Transaction transaction = dao.startTransaction();
        dao.getQuickDAOConfig().transactionThreadLocal.set(transaction);
        logger.trace("获取事务对象! 事务对象:{},DAO:{}", transaction, dao);
        return transaction;
    }

    @Override
    protected void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException {
        Transaction transactionDAO = (Transaction) transaction;
        logger.trace("开启事务!事务隔离级别:{},事务:{},DAO:{}", definition.getIsolationLevel(), transaction, dao);
        int isolationLevel = definition.getIsolationLevel();
        switch (isolationLevel){
            case TransactionDefinition.ISOLATION_DEFAULT:{}break;
            case TransactionDefinition.ISOLATION_READ_UNCOMMITTED:{
                transactionDAO.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
            }break;
            case TransactionDefinition.ISOLATION_READ_COMMITTED:{
                transactionDAO.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
            }break;
            case TransactionDefinition.ISOLATION_REPEATABLE_READ:{
                transactionDAO.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
            }break;
            case TransactionDefinition.ISOLATION_SERIALIZABLE:{
                transactionDAO.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
            }break;
        }
    }

    @Override
    protected void doCommit(DefaultTransactionStatus status) throws TransactionException {
        Transaction transaction = (Transaction) status.getTransaction();
        logger.trace("提交事务,事务对象:{},DAO:{}", transaction, dao);
        transaction.commit();
    }

    @Override
    protected void doRollback(DefaultTransactionStatus status) throws TransactionException {
        Transaction transaction = (Transaction) status.getTransaction();
        logger.trace("回退事务,事务对象:{},DAO:{}", transaction, dao);
        transaction.rollback();
    }
}
